﻿    using System;
using System.Collections.Generic;
using BusTrackerSystem.Model;
using System.Timers;
using System.Net;
using BusTrackerSystem.Utility;

namespace BusTrackerSystem.Repository
{
    public class LothianBusTrackerRepository : IBusTimesRepository
    {
        public event EventHandler LatestTimesUpdated;
        public event EventHandler LatestTimeError;

        private const string RETRIEVAL_URL_DOMAIN = "http://old.mybustracker.co.uk/getBusStopDepartures.php";
        private List<BusTime> _busTimes;
        private string _busStopCode;
        private Timer _timer;
        private int _scanFrequency;
        private int _numberOfBusTimes;
        private string _errorMessage;

        public LothianBusTrackerRepository()
        {
            ScanFrequency = 30000;
            _timer = new Timer(ScanFrequency);
            _timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
        }

        public int ScanFrequency
        {
            get { return _scanFrequency; }
            set
            {
                if (_scanFrequency == value) return;

                _scanFrequency = value;

                if (_timer != null)
                {
                    _timer.Interval = _scanFrequency * 1000;
                }
            }
        }

        public List<BusTime> BusTimes
        {
            get { return _busTimes; }
            private set
            {
                if (_busTimes == value) return;

                _busTimes = value;
                OnLatestTimesUpdated();
            }
        }

        public void BeginScanningLatestTimes(string busStopCode, int numberOfBusTimes)
        {
            _busStopCode = busStopCode;
            _numberOfBusTimes = numberOfBusTimes;
            //Initial scan - this will start the timer
            ScanLatestTimes();
        }

        public void StopScanningLatestTimes()
        {
            _timer.Stop();
        }

        private void _timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            _timer.Stop();
            ScanLatestTimes();
        }

        private void ScanLatestTimes()
        {          
            WebResponse response = null;
            //TODO: Scan url with this bus stop code asynchronously, use ScanLatestTimesCompleted on completion
            string url = String.Format(RETRIEVAL_URL_DOMAIN + "?clientType=b&busStopCode={0}&numberOfPassage={1}", _busStopCode, _numberOfBusTimes);

            System.Diagnostics.Debug.WriteLine(url);

            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "GET";
                //Pretend we are mozilla... shhhh
                request.UserAgent = "Mozilla/4.0";
                response = request.GetResponse();
                BusTimes = MyBusTrackerParser.ParseBusTimeInformation(response);
            }
            catch (System.Net.WebException webException)
            {
                //TODO: Log exception
                ErrorMessage = webException.Message;
                //Reset bus times
                BusTimes = null;
            }
            catch (Exception ex)
            {
                ErrorMessage = ex.Message;
                //Reset bus times
                BusTimes = null;
            }
            
            ScanLatestTimesCompleted();
        }

        private void ScanLatestTimesCompleted()
        {
            //On completion  - reset the timer
            _timer.Stop();
            _timer.Start();
        }

        private void OnLatestTimesUpdated()
        {
            //Reset error message when successfully retrieved times
            ErrorMessage = "";
            if (LatestTimesUpdated != null)
                LatestTimesUpdated(this, new EventArgs());
        }

        private void OnLatestTimeError()
        {
            if (LatestTimeError != null)
                LatestTimeError(this, new EventArgs());
        }

        public string ErrorMessage
        {
            get { return _errorMessage; }
            set
            {
                if (_errorMessage != value)
                    _errorMessage = value;
                OnLatestTimeError();
            }
        }
    }
}
